//
//		XR16L78X UART DRIVER
//
//      (c) 2008 mocom software GmbH & Co KG 
//		for European Microsoft Innovation Center
//
//      $Author: volker $
//      $Date: 2009-09-16 11:15:21 +0200 (Mi, 16. Sep 2009) $
//      $Revision: 493 $
//
//		Driver autodetects number of channels:
//
//		XR16C784 = 4 channels
//		XR16C788 = 8 channels
//
#ifndef H_XR16L78X
#define H_XR16L78X

//// some .NET MF 3.0 defines not available with 2.5
#ifndef USART_PARITY_NONE
#define USART_PARITY_NONE  				0
#define USART_PARITY_ODD   				1
#define USART_PARITY_EVEN  				2
#define USART_PARITY_MARK  				3
#define USART_PARITY_SPACE 				4
#endif

#ifndef USART_STOP_BITS_NONE
#define USART_STOP_BITS_NONE          	0
#define USART_STOP_BITS_ONE           	1
#define USART_STOP_BITS_TWO           	2
#define USART_STOP_BITS_ONEPOINTFIVE  	3
#endif

#ifndef USART_FLOW_HALF_DUPLEX
#define USART_FLOW_HALF_DUPLEX   		0x8000
#endif
//// END .NET MF 3.0


////// CONFIG --- serial input clk, lowest logical channel number and RS485 delay in bittimes
#define XR16L78X_INPUT_CLK 				29000000
#define XR16L78X_RS485_DELAY			2
#define XR16L78X_FIFO_SIZE				64
//////

#define XR16L78X_DIV0	data
#define XR16L78X_DIV1	ier
#define XR16L78X_FIFO	isr

// industry standard 16450 compatible registers
typedef __packed volatile struct {
	UINT8	data;		// 0 transmitter and receiver holding	, if LCR[7] = 0
	UINT8	ier;		// 1 interruot enable, if LCR[7] = 0
	UINT8	isr;		// 2 read: interrupt status, write: fifo ctrl
	UINT8	lcr;		// 3 line control register
	UINT8	mcr;		// 4 modem control register
	UINT8	lsr;		// 5 line status register
	UINT8	msr;		// 6 read: modem status register, write: rs485 turnaround delay
	UINT8	spr;		// 7 scratch pad register
// XR16L78X enhanced registers
	UINT8	fctr;		// 8 feature control register
	UINT8	efr;		// 9 enhanced function register
	UINT8	txfifo;		// A read: tx fifo level counter, read: tx fifo trigger level
	UINT8	rxfifo;		// B read: rx fifo level counter, read: rx fifo trigger level
	UINT8	xoff1;		// C xoff char 1
	UINT8	xoff2;		// D xoff char 2
	UINT8	xon1;		// E xon char 1
	UINT8	xon2;		// F xon char 2
} XR16L78XUart;

// XR16L78X config registers 80-8f
typedef __packed volatile struct {
	UINT32	isr;		// 0 int pending bits & status indicators
	UINT8	tctr;		// 4 timer control
	UINT8	timer_res;	// 5 reserved
	UINT16	timer;		// 6 tconst, tvalue
	UINT8	sample;		// 8 X8 or X16, X16 default
	UINT8	reserved;	// 9
	UINT8	reset;		// A set bit 0..N to reset a uart epective
	UINT8	sleep;		// B set bit 0..N to set sleep mode
	UINT8	revision;	// C device revision
	UINT8	device;		// D device ID
	UINT8	regb;		// E write global feature enable
} XR16L78XChipConfig;

typedef __packed volatile struct {
	XR16L78XUart		ch[8];
	XR16L78XChipConfig	config;
} XR16L78XChip;


// defaults
#define XR16L78X_NO_PARITY      	0x00
#define XR16L78X_ODD_PARITY      	0x08
#define XR16L78X_EVEN_PARITY     	0x18
#define XR16L78X_PARITY_SET      	0x28
#define XR16L78X_PARITY_CLR      	0x38

#define XR16L78X_2_STOP_BITS	    0x04
#define XR16L78X_1_STOP_BITS	    0x00

#define XR16L78X_5_BITS	        	0x00
#define XR16L78X_6_BITS	        	0x01
#define XR16L78X_7_BITS	        	0x02
#define XR16L78X_8_BITS	        	0x03

#define XR16L78X_ERR_OVERRUN		0x02
#define XR16L78X_ERR_PARITY	    	0x04
#define XR16L78X_ERR_FRAMING		0x08
#define XR16L78X_ERR_BREAK	    	0x10

// IRQ-Enable-Register (IER)
#define XR16L78X_IER_RECEIVED    	0x01            // IRQ on receive  
#define XR16L78X_IER_SENT        	0x02            // IRQ after byte sent  
#define XR16L78X_IER_LINE        	0x04            // IRQ line status change  
#define XR16L78X_IER_MODEM       	0x08            // IRQ modem status change 

// ISR
#define XR16L78X_ID_PENDING      	0x01            // IRQ pending?
#define XR16L78X_ID_MASK         	0x06            // ID Bit 1 & 2
#define XR16L78X_ID_LINESTATUS   	0x06            // Error or Break 
#define XR16L78X_ID_RECEIVED     	0x04            // Data received
#define XR16L78X_ID_SENT         	0x02            // Byte sent
#define XR16L78X_ID_MODEMSTATUS  	0x00            // CTS, DSR, RI etc

// FIFO-Register 
#define XR16L78X_FIFO_ENABLE     	0x01
#define XR16L78X_FIFO_RX_FLUSH   	0x02
#define XR16L78X_FIFO_TX_FLUSH   	0x04
#define XR16L78X_FIFO_FLUSH      	0x06

// FIFO-Bits
#define XR16L78X_FIFO_TRIGGER1   	0x00            // std  
#define XR16L78X_FIFO_TRIGGER4   	0x40            // 4 Bytes  
#define XR16L78X_FIFO_TRIGGER8   	0x80            // 8 Bytes  
#define XR16L78X_FIFO_TRIGGER14  	0xC0            // 14 Bytes  


// Line-Control-Register
#define XR16L78X_LCR_WORDLEN     	0x03            // number of bits per char
#define XR16L78X_LCR_5BITS       	XR16L78X_5_BITS		// set XR16L78X_LCR_WORDLEN to 5
#define XR16L78X_LCR_6BITS       	XR16L78X_6_BITS		// set XR16L78X_LCR_WORDLEN to 6
#define XR16L78X_LCR_7BITS       	XR16L78X_7_BITS		// set XR16L78X_LCR_WORDLEN to 7
#define XR16L78X_LCR_8BITS       	XR16L78X_8_BITS		// set XR16L78X_LCR_WORDLEN to 8
#define XR16L78X_LCR_2STOPBITS   	XR16L78X_2_STOP_BITS // 2, 1.5 Stopbits 
#define XR16L78X_LCR_1STOPBIT    	XR16L78X_1_STOP_BIT  // 1 Stopbit  

#define XR16L78X_LCR_NOPARITY    	XR16L78X_NO_PARITY   // no parity
#define XR16L78X_LCR_ODDPARITY   	XR16L78X_ODD_PARITY  // odd parity
#define XR16L78X_LCR_EVENPARITY  	XR16L78X_EVEN_PARITY // even parity
#define XR16L78X_LCR_PARITYSET   	XR16L78X_PARITY_SET  // mark parity
#define XR16L78X_LCR_PARITYCLR   	XR16L78X_PARITY_CLR  // space parity
#define XR16L78X_LCR_PARITYMSK   	0x38			

#define XR16L78X_LCR_SENDBREAK   	0x40            // send break while this bit is set
#define XR16L78X_LCR_SETDIVISOR  	0x80            // access to BR divider

// Modem-Control-Register
#define XR16L78X_MCR_DTR         	0x01            // DTR
#define XR16L78X_MCR_RTS         	0x02            // RTS
#define XR16L78X_MCR_UNUSED      	0x04
#define XR16L78X_MCR_IRQENABLED  	0x08            // IRQ enable
#define XR16L78X_MCR_LOOP        	0x10            // loopback
#define XR16L78X_MCR_IRDA_ON      	0x40            
#define XR16L78X_MCR_PRESCALE      	0x80            /// divide by 4	

// Line-Status-Register
#define XR16L78X_LSR_RXAVAIL     	0x01            // data available
#define XR16L78X_LSR_OVERRUN     	ERR_OVERRUN     // rx overrun
#define XR16L78X_LSR_PARITY      	ERR_PARITY      // parity error
#define XR16L78X_LSR_FRAMING     	ERR_FRAMEING    // framing error
#define XR16L78X_LSR_BREAK       	ERR_BREAK       // break detected
#define XR16L78X_LSR_THREMPTY    	0x20			// transmit holding reg empty
#define XR16L78X_LSR_TSREMPTY    	0x40			// transmit shift reg empty
#define XR16L78X_LSR_MASK        	0x1f			// mask	

// Modem Status Register 
#define XR16L78X_MSR_DCTS        	0x01            // Delta CTS 
#define XR16L78X_MSR_DDSR        	0x02            // Delta DSR 
#define XR16L78X_MSR_DRI         	0x04            // Delta RI 
#define XR16L78X_MSR_DCD         	0x08            // Delta CD 
#define XR16L78X_MSR_CTS         	0x10            // Clear To Send
#define XR16L78X_MSR_DSR         	0x20            // Data Set Ready
#define XR16L78X_MSR_RI          	0x40            // Rin Indicator
#define XR16L78X_MSR_CD          	0x80            // Carrier Detect

// enhanced registers fctr
#define XR16L78X_FCTR_TRG_SEL		0xc0			// set fifo levels via txfifo/rxfifo register				
#define XR16L78X_FCTR_RS485_ON		0x20			// enable auto rs485
#define XR16L78X_FCTR_IRDA_INV		0x10			// rx invert irda signal

// enhanced register efr
#define XR16L78X_EFR_AUTO_DRTS		0x40
#define XR16L78X_EFR_AUTO_CTS		0x80

// timer control register (tctr in config space)
#define XR16L78X_TCTR_CLK_PIN		0x08
#define XR16L78X_TCTR_CLK_OSC		0x00
#define XR16L78X_TCTR_ONE_SHOT		0x04
#define XR16L78X_TCTR_PERIODIC		0x00
#define XR16L78X_TCTR_START			0x02
#define XR16L78X_TCTR_STOP			0x00
#define XR16L78X_TCTR_INT_ENABLE	0x01
#define XR16L78X_TCTR_INT_DISABLE	0x00

#ifndef H_JACK_INC

//////////////////////////////////////////////////////////////////////////////
// XR16L78X_USART_Driver
//
struct XR16L78X_USART_Driver
{
	// basic constants
	int  channels;							// is set to 8 for 16L788
											// and 4 for the  16L784
	XR16L78XChip *chip;
	
	//--//
    INT8 	m_RefFlags[8];	
	UINT8	m_RqFlags[8];
	
	UINT32	m_ChannelOpen;
	
	struct {
		int 	(*m_LineIsrCallback)(int,unsigned,unsigned,void *);	
		void 	*m_LineParam;
		int 	(*m_ModemIsrCallback)(int,int,bool,void *);	
		void 	*m_ModemParam;
		int 	(*m_RxIsrCallback)(int,unsigned,UINT8 volatile *,void *);	
		void 	*m_RxParam;
		int 	(*m_TxIsrCallback)(int,unsigned,UINT8 volatile *,void *);	
		void 	*m_TxParam;
	} redirect[8];
		
	//--//
    static BOOL Initialize( int comPort, int baudRate, int Parity, int DataBits, int StopBits, int flowValue );
    static BOOL Uninitialize( int comPort );
    static BOOL TxBufferEmpty( int comPort );
    static BOOL TxShiftRegisterEmpty( int comPort );
    static void WriteCharToTxBuffer( int comPort,  UINT8 c );
    static unsigned WriteBurstToTxBuffer( int comPort,  UINT8 *data, unsigned len );
    static void TxBufferEmptyInterruptEnable( int comPort, BOOL enable );
    static BOOL TxBufferEmptyInterruptState( int comPort );
    static void RxBufferFullInterruptEnable( int comPort, BOOL enable );
    static BOOL RxBufferFullInterruptState( int comPort );
    static BOOL TxHandshakeEnabledState( int comPort );
    static void ProtectPins( int comPort, BOOL on );
#ifdef XR16L78X_USART_USE_PIO_IRQ
	static void USART_GPIOISRVector( GPIO_PIN Pin, BOOL PinState, void* Param );
#else
    static void USART_ISR( void *x );
#endif	
    static void GetPins( int comPort,  GPIO_PIN& rxPin, GPIO_PIN& txPin,GPIO_PIN& ctsPin, GPIO_PIN& rtsPin );    
    static void BaudrateBoundary( int ComPortNum, UINT32& maxBaudrateHz, UINT32& minBaudrateHz );
    static BOOL IsBaudrateSupported( int ComPortNum, UINT32 & BaudrateHz );    

	static BOOL GetOption(int ComPortNum, int Feature, UINT32 *Value);
	static BOOL SetOption(int ComPortNum, int Feature, UINT32 Value);	
	//--//
	
	
};
//
// XR16L78X_USART_Driver
//////////////////////////////////////////////////////////////////////////////

#endif
#endif
